﻿//========================================================================
// *作者：海盗猫  主页：ilplay.com
// *脚本：EditorMenuHandle
// *描述：EditorMenuHandle
// *?2024 HDMCode . All rights reserved.
//* ======================================================================
using System;
using System.Collections.Generic;
using System.IO;
using HDMCode.FrameEditor;
using HDMCode.UIFrame;
using UnityEditor;
using UnityEngine;
namespace HDMCode.UIFrameEditor
{
    public class EditorMenuHandle
    {
        /// <summary>
        /// 检查文件是否存在
        /// </summary>
        /// <param name="creatDate">需要创建的信息</param>
        /// <returns>返回结果</returns>
        public bool CheckFile(EditorCreatDate creatDate)
        {
            var prefabGuids = AssetDatabase.FindAssets("t:Prefab", new []{EditorBaseDate.Setting.AssetsPath});
            var scriptGuids = AssetDatabase.FindAssets("t:Script",new []{EditorBaseDate.Setting.ScriptPath});
            foreach (var item in prefabGuids)
            {
                var file = Path.GetFileName(AssetDatabase.GUIDToAssetPath(item));
                if (string.Equals($"{creatDate.CreatName}.prefab",file))
                    return true;
            }
            
            foreach (var item in scriptGuids)
            {
                var file = Path.GetFileName(AssetDatabase.GUIDToAssetPath(item));
                if (string.Equals($"{creatDate.CreatName}.cs",file))
                    return true;
            }
            return false;
        }

        /// <summary>
        /// 检查文件夹路径是否已经存在
        /// </summary>
        /// <param name="creatDate">需要创建的信息</param>
        /// <param name="path">当前路径</param>
        /// <param name="isOlnyCrat"></param>
        /// <returns>是否拥有异常</returns>
        public bool CheckFloder(EditorCreatDate creatDate,out string path,bool isOlnyCrat = false)
        {
            path = default;
            var assetPath = GetPath(creatDate, EditorBaseDate.FileType.Asset);
            var scriptPath = GetPath(creatDate, EditorBaseDate.FileType.Script);

            Check(EditorBaseDate.Setting.AssetsPath);
            Check(EditorBaseDate.Setting.ScriptPath);
            Check(assetPath.groupPath);
            Check(scriptPath.groupPath);
            
            if (Check(scriptPath.floderPath))
            {
                path = scriptPath.floderPath;
                if (isOlnyCrat is false)
                    return true;
            }
            
            if (Check(assetPath.floderPath))
            {
                path = assetPath.floderPath;
                if (isOlnyCrat is false)
                    return true;
            }
            
            bool Check(string path)
            {
                if (!Directory.Exists(path))
                {
                    Directory.CreateDirectory(path);
                    return false;
                }
                else
                    return true;
            }
            return false;
        }

        /// <summary>
        /// 获取资源不同路径
        /// </summary>
        /// <param name="creatDate">需要创建的信息</param>
        /// <param name="file">路径类型</param>
        /// <returns>返回不同路径</returns>
        public (string groupPath,string floderPath,string filePath,string genFilePath) GetPath(EditorCreatDate creatDate,EditorBaseDate.FileType file)
        {
            string groupPath = file switch
            {
                EditorBaseDate.FileType.Asset => $"{EditorBaseDate.Setting.AssetsPath}/{EditorBaseDate.Setting.Groups[creatDate.Group]}",
                EditorBaseDate.FileType.Script => $"{EditorBaseDate.Setting.ScriptPath}/{EditorBaseDate.Setting.Groups[creatDate.Group]}",
                _ => throw new ArgumentOutOfRangeException(nameof(file), file, null)
            };
            string floderPath = $"{groupPath}/{creatDate.CreatName}";
            string filePath = file switch
            {
                EditorBaseDate.FileType.Asset => $"{floderPath}/{creatDate.CreatName}.prefab",
                EditorBaseDate.FileType.Script => $"{floderPath}/{creatDate.CreatName}.cs",
                _ => throw new ArgumentOutOfRangeException(nameof(file), file, null)
            };
            string genFilePath = $"{floderPath}/HDMAuto{creatDate.CreatName}.cs";
            return (groupPath, floderPath, filePath,genFilePath);
        }

        /// <summary>
        /// 创建预制体资源
        /// </summary>
        /// <param name="creatDate">需要创建的信息</param>
        public UIDisplay CreatPrefabAssets(EditorCreatDate creatDate)
        {
            GameObject netAsset = new GameObject(creatDate.CreatName,new Type[]{typeof(RectTransform),typeof(CanvasRenderer)});
            var uIDisplay = netAsset.AddComponent<UIDisplay>();
            uIDisplay.components ??= new List<UIComponentElement>();
            uIDisplay.components.Add(new UIComponentElement(){ target = netAsset });
            var path = GetPath(creatDate,EditorBaseDate.FileType.Asset);
            PrefabUtility.SaveAsPrefabAssetAndConnect(netAsset,path.filePath, InteractionMode.UserAction);
            creatDate.Guid = AssetDatabase.AssetPathToGUID(EditorHelper.SystemPathChangeProjectPath(path.filePath));
            if (!creatDate.IsLoadToScene)
                UnityEngine.Object.DestroyImmediate(netAsset);
            if (EditorUtility.DisplayDialog("成功提示：", $"资源创建成功，是否打开资源！", "打开","完成"))
            {
                HDMEditorHelper.SeletFile(EditorHelper.SystemPathChangeProjectPath(path.filePath));
            }
            return uIDisplay;
        }

        /// <summary>
        /// 创建脚本资源
        /// </summary>
        /// <param name="creatDate">需要创建的信息</param>
        /// <param name="components">组件信息</param>
        /// <param name="scriptType">需要生产的脚本类型</param>
        public void CreatScriptAssets(EditorCreatDate creatDate,List<UIComponentElement> components,EditorBaseDate.ScriptType scriptType= EditorBaseDate.ScriptType.All)
        {
            var path = GetPath(creatDate,EditorBaseDate.FileType.Script);
            switch (scriptType)
            {
                case EditorBaseDate.ScriptType.Gen:
                    DrawScriptTemplate.CreatScript(creatDate.CreatName, creatDate.CreatName,"IUIFrameComponent", $"{path.floderPath}/",components);
                    break;
                case EditorBaseDate.ScriptType.Lift:
                    DrawLifeScriptTemplate.CreatScript(path.filePath, creatDate.CreatName, creatDate.Describe);
                    break;
                case EditorBaseDate.ScriptType.All:
                    DrawLifeScriptTemplate.CreatScript(path.filePath, creatDate.CreatName, creatDate.Describe);
                    DrawScriptTemplate.CreatScript(creatDate.CreatName, creatDate.CreatName,"IUIFrameComponent", $"{path.floderPath}/",components);
                    break;
            }
            AssetDatabase.Refresh();
        }

        /// <summary>
        /// 添加到设置文件
        /// </summary>
        /// <param name="creatDate">需要创建的信息</param>
        public void AddInfoToSetting(EditorCreatDate creatDate)
        {
            EditorBaseDate.Setting.UISettings.Add(creatDate);
            EditorUtility.SetDirty(EditorBaseDate.Setting);
            AssetDatabase.SaveAssets();
        }
        
        /// <summary>
        /// 从设置中移除
        /// </summary>
        /// <param name="creatDate">需要创建的信息</param>
        public void RemoveInfoToSetting(EditorCreatDate creatDate)
        {
            EditorCreatDate tamp = default;
            for(int i = 0 ; i < EditorBaseDate.Setting.UISettings.Count ; i++)
            {
                if (creatDate.CreatName == EditorBaseDate.Setting.UISettings[i].CreatName)
                    tamp = EditorBaseDate.Setting.UISettings[i];
            }
            int index = Array.IndexOf(EditorBaseDate.Setting.UISettings.ToArray(), tamp);
            EditorBaseDate.Setting.UISettings.RemoveAt(index);
            EditorUtility.SetDirty(EditorBaseDate.Setting);
            AssetDatabase.SaveAssets();
        }

        /// <summary>
        /// 获取组的下标
        /// </summary>
        /// <param name="groupName">获取组的名称</param>
        /// <returns></returns>
        public int GetGroupIndex(string groupName)
        {
            return Array.IndexOf(EditorBaseDate.Setting.Groups, groupName);
        }
    }
}
